package daos

import (
	"fmt"
	"gorm.io/gorm"
	"gorm.io/gorm/clause"
	"sanrenx.com/xyxf/app/models"
	"sanrenx.com/xyxf/pkg/orm"
	"strconv"
)

/**
 * @Description: 问答
 */
type IssueDao struct {
	DB *gorm.DB
}

/**
 * @Description: 问题数量
 * @receiver dao
 * @return count 数量
 * @return err 异常信息
 */
func (dao *IssueDao) GetIssueCount(maps map[string]interface{}) (count int64, err error) {

	//克隆maps 避免后续使用缺值
	cloneMaps := make(map[string]interface{})
	for k, v := range maps {
		cloneMaps[k] = v
	}

	tx := orm.DB.Table("issue")

	//如果有title 模糊查询
	if val, ok := cloneMaps["title"]; ok {
		title := fmt.Sprintf("%v", val)
		tx = tx.Where("title LIKE ?", "%"+title+"%")
		delete(cloneMaps, "title")
	}

	//条件查询存在
	if len(cloneMaps) > 0 {
		tx = tx.Where(cloneMaps)
	}

	if err = tx.Count(&count).Error; err != nil {
		return 0, err
	}

	//返回数量
	return count, nil
}

/**
 * @Description: 获取问题列表column
 * @receiver dao
 * @param offset 起始
 * @param size 数量
 * @param orderBy 排序
 * @return ids 问题ID数组
 * @return list 问题Column数组
 * @return err 异常信息
 */
func (dao *IssueDao) GetPageIssueColumn(maps map[string]interface{}, offset int, size int, orderBy string) (ids []string, list []*models.IssueColumn, err error) {

	tx := dao.DB.Table("issue").
		Select([]string{
			"id",
			"same",
			"praise",
		})

	//克隆maps 避免后续使用缺值
	cloneMaps := make(map[string]interface{})
	for k, v := range maps {
		cloneMaps[k] = v
	}

	//如果有title 模糊查询
	if val, ok := cloneMaps["title"]; ok {
		title := fmt.Sprintf("%v", val)
		tx = tx.Where("title LIKE ?", "%"+title+"%")
		delete(cloneMaps, "title")
	}

	//条件查询存在
	if len(cloneMaps) > 0 {
		tx = tx.Where(cloneMaps)
	}

	//排序方式
	if orderBy == models.OrderIssueSame {
		tx.Order("same DESC")
	} else if orderBy == models.OrderIssuePraise {
		tx.Order("praise DESC")
	} else {
		tx.Order("created_at DESC")
	}

	if err = tx.Offset(offset).
		Limit(size).
		Find(&list).
		Error; err != nil && err != gorm.ErrRecordNotFound {
		return nil, nil, err
	}

	//提出IDs
	for _, item := range list {
		ids = append(ids, strconv.FormatUint(item.ID, 10))
	}

	return ids, list, nil
}

/**
 * @Description: 获取问题详情
 * @receiver dao
 * @param id 问题ID
 * @return *models.IssueDetails 问题详情
 * @return error 异常信息
 */
func (dao *IssueDao) GetIssue(id uint64) (*models.IssueDetails, error) {

	var data models.IssueDetails

	if err := dao.DB.Unscoped().
		Table("issue").
		Preload(clause.Associations). //预加载全部关联
		First(&data, id).
		Error; err != nil && err != gorm.ErrRecordNotFound {
		return nil, err
	}

	return &data, nil
}

/**
 * @Description: 保存问题
 * @receiver dao
 * @param data 数据
 * @return id 问题ID
 * @return err 异常信息
 */
func (dao *IssueDao) NewIssue(uid uint64, title string, anon bool) (id uint64, err error) {

	var data = struct {
		ID     uint64
		UserID uint64
		Title  string
		Anon   bool
	}{
		UserID: uid,
		Title:  title,
		Anon:   anon,
	}

	if err := dao.DB.Table("issue").Create(&data).
		Error; err != nil {
		return 0, err
	}

	return data.ID, nil
}

/**
 * @Description: 增长问题属性
 * @receiver dao
 * @param id 问题ID
 * @param mode 属性
 * @param incNum 增长值
 * @return error 异常信息
 */
func (dao *IssueDao) IncrIssue(id uint64, mode string, incNum int) error {
	exprKey := fmt.Sprintf("%s + ?", mode)
	if err := dao.DB.Table("issue").
		Where("id = ?", id).
		UpdateColumn(mode, gorm.Expr(exprKey, incNum)).
		Error; err != nil {
		return err
	}

	return nil
}
